package com.itfreer.arcgis;

import com.esri.arcgisruntime.arcgisservices.LabelDefinition;
import com.esri.arcgisruntime.concurrent.ListenableFuture;
import com.esri.arcgisruntime.data.FeatureQueryResult;
import com.esri.arcgisruntime.data.FeatureTable;
import com.esri.arcgisruntime.data.Field;
import com.esri.arcgisruntime.data.QueryParameters;
import com.esri.arcgisruntime.geometry.Envelope;
import com.esri.arcgisruntime.geometry.GeometryType;
import com.esri.arcgisruntime.geometry.Point;
import com.esri.arcgisruntime.layers.FeatureLayer;
import com.esri.arcgisruntime.mapping.view.MapView;
import com.esri.arcgisruntime.symbology.SimpleLineSymbol;
import com.itfreer.arcgis.query.GetSelectFeatureListener;
import com.itfreer.arcgis.symbol.SymbolStyleType;
import com.itfreer.arcgis.symbol.SymbolUtils;
import com.itfreer.utils.ColorUtils;

/**
 * 图层对象
 */
public class LayerUtils
{
    /**
     * 根据矢量数据要素对象创建图层对象
     * @param featureTable 数据对象
     * @return
     */
    public static FeatureLayer CreateFeatureLayerFormTable(FeatureTable featureTable)
    {
        // 构建FeatureLayer
        FeatureLayer featureLayer = new FeatureLayer(featureTable);
        return  featureLayer;
    }


    /**
     * 更新点图层样式
     * @param featureLayer
     */
    public static void UpdatePointLayerStyle(FeatureLayer  featureLayer,String hexColor,float size)
    {
        if(featureLayer == null || featureLayer.getFeatureTable().getGeometryType() != GeometryType.POINT)
            return;
        featureLayer.setRenderer(SymbolUtils.GetRenderer(SymbolUtils.GetPointSymbol(SymbolStyleType.PointType.CIRCLE,
                ColorUtils.Hex2Int(hexColor),size)));
    }

    /**
     * 更新面图层样式
     * @param featureLayer
     */
    public static void UpdateLineLayerStyle(FeatureLayer featureLayer,String hexColor,float size)
    {
        if(featureLayer == null || featureLayer.getFeatureTable().getGeometryType() != GeometryType.POLYLINE)
            return;
        featureLayer.setRenderer(SymbolUtils.GetRenderer(SymbolUtils.GetPolylineSymbol(SymbolStyleType.PolylineType.SOLID,
                ColorUtils.Hex2Int(hexColor),size)));
    }

    /**
     * 更新面图层样式
     * @param featureLayer
     */
    public static void UpdatePolygonLayerStyle(FeatureLayer featureLayer, String hexColor, float size, SimpleLineSymbol outLineSymbol)
    {
        if(featureLayer == null || featureLayer.getFeatureTable().getGeometryType() != GeometryType.POLYGON)
            return;
        featureLayer.setRenderer(SymbolUtils.GetRenderer(SymbolUtils.GetPolygonSymbol(SymbolStyleType.PolygonType.SOLID,
                ColorUtils.Hex2Int(hexColor),outLineSymbol)));
    }

    /**
     * 重置图层样式
     * @param featureLayer
     */
    public static  void ResetSymbol(FeatureLayer featureLayer)
    {
        if(featureLayer == null)
            return;

        featureLayer.resetRenderer();
    }

    /**
     * 点选要素
     * @param point 点对象
     * @param mapView 地图对象
     * @param featureLayer 图层对象
     */
    public static  void SelectFeatures(Point point, MapView mapView, FeatureLayer featureLayer)
    {
        int tolerance = 2;
        if(featureLayer.getFeatureTable().getGeometryType() == GeometryType.POINT)
            tolerance = 10;
        else if(featureLayer.getFeatureTable().getGeometryType() == GeometryType.POLYLINE)
            tolerance = 5;
        double mapTolerance = tolerance * mapView.getUnitsPerDensityIndependentPixel();
        // create objects required to do a selection with a query
        Envelope envelope = new Envelope(point.getX() - mapTolerance, point.getY() - mapTolerance, point.getX() + mapTolerance, point.getY() + mapTolerance, mapView.getMap().getSpatialReference());
        QueryParameters query = new QueryParameters();
        query.setGeometry(envelope);
        // call select features
        final ListenableFuture<FeatureQueryResult> future = featureLayer.selectFeaturesAsync(query, FeatureLayer.SelectionMode.NEW);
    }

    /**
     * 获取选中要素并回调
     * @param featureLayer
     */
    public static void GetSelectFeature(final FeatureLayer featureLayer, final GetSelectFeatureListener listener)
    {
        if(featureLayer == null || listener == null)
            return;
        final ListenableFuture<FeatureQueryResult> selected = featureLayer.getSelectedFeaturesAsync();
        selected.addDoneListener(new Runnable()
        {
            @Override
            public void run()
            {
                try
                {
                    listener.execute(featureLayer,selected);
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * 显示图层标注
     * @param featureLayer
     * @param color
     * @param showField
     */
    public static  void ShowFeatureLayerLabel(FeatureLayer featureLayer,String color, Field showField)
    {
        int[] rgbColor = ColorUtils.Hex2Rgb(color);
        String addressLabelsJson = "{" +
                "\"labelExpressionInfo\": {" + // Define a labeling expression that will show the address attribute value
                "\"expression\": \"return $feature."+showField.getName()+";\"}," +
                "\"labelPlacement\": \"esriServerPolygonPlacementAlwaysHorizontal\"," + // Align labels horizontally
                "\"symbol\": {" + // Use a green bold text symbol
                "\"color\": ["+rgbColor[0]+","+rgbColor[1]+","+rgbColor[2]+ ",255]," +
                "\"font\": {\"size\": 18, \"weight\": \"bold\"}," +
                "\"type\": \"esriTS\"}" +
                "}";

        // Create a new LabelDefintion object using the static FromJson method
        LabelDefinition labelDef = LabelDefinition.fromJson(addressLabelsJson);

        // Clear the current collection of label definitions (if any)
        featureLayer.getLabelDefinitions().clear();

        // Add this label definition to the collection
        featureLayer.getLabelDefinitions().add(labelDef);

        // Make sure labeling is enabled for the layer
        featureLayer.setLabelsEnabled(true);
    }

    /**
     * 隐藏图层标注
     * @param featureLayer
     */
    public static  void HiddenFeatureLayerLabel(FeatureLayer featureLayer)
    {
        featureLayer.getLabelDefinitions().clear();
        featureLayer.setLabelsEnabled(false);
    }
}
